/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package restinterpreter;
/**
 * @author Klaus Versl
 */
import java.net.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class ChannelREST {
  private String urlString;
  private String HttpReply;
  private int ts[];
  private double value[];
  private boolean HttpReplyToBeParsed = false; //
  // private int i;
  
  boolean setUrlString(String input){
	  /* 
	   * set String urlString  &&  return true
	   * if urlString is a valid url.
	   * else return false.
	   *
	   *  This RegEx matches valid url strings:
	   * ^(http|https)\://[a-zA-Z0-9\-]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*$  
	   */
      String regex = "^(http|https)\\://[a-zA-Z0-9\\-]+\\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\\-\\._\\?\\,\\'/\\\\\\+&amp;%\\$#\\=~])*$";
      // compile the given RegEx into a pattern
      Pattern pattern = Pattern.compile(regex);
      Matcher matcher = pattern.matcher(input);
       // true if urlString is valid
      boolean b = matcher.find();
      if (b) this.urlString = input;
      return b;
  }
  
  String getUrlString(){
	  return urlString;
  }
  
  int getTsLength(){
	  return ts.length;
  }
  
  int getTs(int i){
	return ts[i];  
  }
  
  double getValue(int i){
	  return value[i];
  }
  
  String queryUrl() {
      // queries an http URL
      // if succesful, stores the Reply to String HttpReply
      String HttpReplyNew="";
      String inputLine;
      try{
          URL url = new URL(urlString);
          URLConnection yc = url.openConnection();
          BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
          
          while ((inputLine = in.readLine()) != null) 
              HttpReplyNew = HttpReplyNew + inputLine+ "\n";
          in.close();
          
          // trim   (remove trailing \n)
          HttpReplyNew = HttpReplyNew.trim();
          // finish
          this.HttpReply = HttpReplyNew;
          HttpReplyToBeParsed = true;
          return("query url GET succesful");
      } catch (Exception e) {
          return("query url GET Error");
      }            
  }
  
  String getHttpReply(){
	  // insert newLine after each pair
	  return HttpReply.replace("},", "},\n");
  }
	  
  boolean parseHttpReply(){
	  /* 
	   * expected reply == "[{"timestamp":"1366353301","value":"4.9"},{"timestamp":"1366353604","value":"30.7"}]"
	   * parses HttpReply into resulting arrays:
	   * ts[i] 		 value[i]  	
	   */
	   if (!HttpReplyToBeParsed) return false;
	   // delete all characters before the first occurence of '['
	   HttpReply.replaceFirst("^.*\\[", "[");
	   HttpReplyToBeParsed = false; // 
	   
	   /*
	    * *** Find the corresponding closing bracket ****
	    * *** Find all positions of [inner] curly braces ***
	    * *** Ignore outer curly braces, if any	****
	    * method: openBraces  counter 
	    * http://stackoverflow.com/questions/524548/regular-expression-to-detect-semi-colon-terminated-c-for-while-loops/524624#524624
	    * preconditions:
	    * opening bracket at pos 0 [
	    * -- [nested] opening curly braces {
	    * -- -- {"strings" or "other characters" within curly braces}
	    * -- corresponding closing curly braces }
	    * closing bracket ]
	    */
	   int openBraces	=0; // level counter: {opening curly brace: openBraces++ ;  closing curly brace}: openBraces-- 
	   int pos			=1;
	   int posClosingDblQu;
	   // corresponging positions of opening and closing braces. Only inner braces.
	   int posOpenBr[] = new int[HttpReply.length()/2]; // max possible length needs
	   int posClosingBr[] = new int[HttpReply.length()/2]; // same length
	   int iBr = 0;	// counts all inner opening braces. 
	   
	   while (pos < HttpReply.length()) {
		   if (HttpReply.charAt(pos) == '{'){
			   openBraces++;
			   // overwrite position posOpenBr[iBr] if previous opening Brace had no closing counterpart
			   posOpenBr[iBr]=pos;
		   } else if (HttpReply.charAt(pos) == '"'){
			   pos++;
			   // jump to closing "  == next occurence of  "
			   posClosingDblQu = HttpReply.indexOf(('"'), pos);
			   if (posClosingDblQu > 0) {
				   pos = posClosingDblQu;
			   } else {
				   // error: missing closing DoubleQuote
				   pos = HttpReply.length()+100; // marks this error for later.
			   }
		   } else if (HttpReply.charAt(pos) == '}') {
			   openBraces--;
			   posClosingBr[iBr]=pos;
			   // increase [iBr] for next opening brace only if it's an inner brace (a direct counterpart to an open brace)
			   if (posOpenBr[iBr] != 0){
				   iBr++;
			   }
		   } else if (openBraces==0){
			   if (HttpReply.charAt(pos) == ']'){
				   // Closing bracket reached.
				   // cut all following text.			   
				   HttpReply = HttpReply.substring(1, pos++).trim();
			   } 
		   } 
		   pos++;
	   }
	   if (openBraces != 0){
		   // unbalanced braces {  }
		   HttpReply = "error in HttpReply: unbalanced braces{}";
		   return false;
	   } else if (pos==HttpReply.length()+101) {
		   HttpReply = "error in HttpReply: missing closing DoubleQuote";
		   return false;
	   }
	   /*
	    * parse pairs of timestamp and value:
	    * {"timestamp":"1366353301","value":"4.9"}
	    *  -------------------s------------------
	    *   ---------s1-----------   -----s2----
	    *               ----ts----           -v-
	    */
	   String s;
	   this.ts	  = new int    [iBr]; // length of arrays as needed
	   this.value = new double [iBr];
	   iBr = 0;
	   // regex Pattern splits sx[0], sx[1]  each into two capturing groups
	   String regex = "\\\"(.*)\\\":\\\"(.*)\\\"";	   
	   Pattern pattern = Pattern.compile(regex);
	   while (posOpenBr[iBr]>0){
		   s  = HttpReply.substring(posOpenBr[iBr]++, posClosingBr[iBr]-1);
		   String[] sx = s.split(",");
		   // regex Pattern splits sx[0]  into two capturing groups: 
		   // 	matcher.group(1) == "timestamp" 
		   //   matcher.group(2) == "123123123" 
	       Matcher matcher = pattern.matcher(sx[0]);
	       if (matcher.find()){
	    	   if (matcher.group(1).equals("timestamp")){
	    		   // TODO String pruefen 
	    		   // allocate converted integer value 
	    		   this.ts[iBr] = Integer.parseInt( matcher.group(2) );
	    	   }
	       } else {
	    	   // if this timestamp is not valid
	    	   // this.ts[iBr] 	  == 0
	    	   // this.value[iBr] == 0.0
	    	   continue;
	       }
		   // regex splits sx[1]  into two capturing groups: 
		   // 	matcher.group(1) == "value" 
		   //   matcher.group(2) == "4.9" 
	       matcher = pattern.matcher(sx[1]);
	       if (matcher.find()){
	    	   if (matcher.group(1).equals("value")){
	    		   // allocate converted double value
	    		   this.value[iBr] = Double.parseDouble( matcher.group(2));
	    	   }
	       } else {
	    	   // if this value is not valid: 
	    	   // this.value[iBr] == 0.0
	       }
	       iBr++;
	   }
	   return true;
  }
}

